package com.foreverwin.mes.lims.service.impl;

import com.foreverwin.mes.common.constants.HandleBOConstants;
import com.foreverwin.mes.common.enums.HandleEnum;
import com.foreverwin.mes.core.base.FrontPage;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.foreverwin.mes.core.exception.BusinessException;
import com.foreverwin.mes.core.utils.StringUtils;
import com.foreverwin.mes.lims.model.InspecArray;
import com.foreverwin.mes.lims.model.InspectProject;
import com.foreverwin.mes.lims.mapper.InspectProjectMapper;
import com.foreverwin.mes.lims.model.InspectProjectDetail;
import com.foreverwin.mes.lims.model.InspectTask;
import com.foreverwin.mes.lims.service.InspecArrayService;
import com.foreverwin.mes.lims.service.InspectProjectDetailService;
import com.foreverwin.mes.lims.service.InspectProjectService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.foreverwin.mes.lims.service.InspectTaskService;
import com.foreverwin.mes.meapi.model.DcGroup;
import com.foreverwin.mes.meapi.model.DcParameter;
import com.foreverwin.mes.meapi.service.DcGroupService;
import com.foreverwin.mes.meapi.service.DcParameterService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Levy
 * @since 2020-02-19
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class InspectProjectServiceImpl extends ServiceImpl<InspectProjectMapper, InspectProject> implements InspectProjectService {


    @Autowired
    private InspectProjectMapper inspectProjectMapper;

    @Autowired
    private InspecArrayService inspecArrayService;

    @Autowired
    private InspectProjectDetailService inspectProjectDetailService;

    @Autowired
    private InspectTaskService inspectTaskService;

    @Autowired
    private DcGroupService dcGroupService;
    @Autowired
    private DcParameterService dcParameterService;

    @Override
    public Page<InspectProject> selectPage(FrontPage<InspectProject> frontPage, InspectProject inspectProject) {
        EntityWrapper<InspectProject> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(inspectProject);
        return super.selectPage(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<InspectProject> selectList(InspectProject inspectProject) {
        EntityWrapper<InspectProject> queryWrapper = new EntityWrapper<>();
        queryWrapper.setEntity(inspectProject);
        return super.selectList(queryWrapper);
    }

    @Override
    public void doSave(InspectProject inspectProject, List<Map> projectList) {
        Date now = new Date();
        int count = 0;
       String site = inspectProject.getSite();
       String projectNo = inspectProject.getProjectNo();
       String revision = inspectProject.getRevision();
       String currentRevision = inspectProject.getCurrentRevision();
       String dataGroupBo = inspectProject.getDataGroup();
       String checkType = inspectProject.getCheckType();
       String user = inspectProject.getCreatedUser();
       String projectHandle = HandleEnum.INSPECT_PROJECT.getHandle( site , projectNo ,checkType , revision );

       //查找数据收集组是否存在
       DcGroup dcGroup =  dcGroupService.selectById( dataGroupBo );
        if ( dcGroup == null){
            throw BusinessException.build("当前版本的数据收集组【"+ dataGroupBo.split(",")[1] +"】不存在");
        }

        //自动取消当前版本数据
        if ( "true".equals( currentRevision ) ){
            inspectProjectMapper.updateCurrentRevision( site , projectNo , now );
        }


        InspectProject oldProject = new InspectProject();
        oldProject.setSite( site );
        oldProject.setProjectNo( projectNo );
        oldProject.setRevision( revision );
        oldProject = inspectProjectMapper.selectOne( oldProject );

        if ( oldProject != null ){
            //更新
            inspectProject.setStatus("Y");
            inspectProject.setCreatedUser( oldProject.getCreatedUser() );
            inspectProject.setCreatedDateTime( oldProject.getCreatedDateTime() );
            inspectProject.setHandle( oldProject.getHandle() );
            inspectProject.setUpdatedDateTime( now );
            inspectProject.setUpdatedUser( user );
            count = inspectProjectMapper.updateAllColumnById( inspectProject );

            if(count <= 0) throw BusinessException.build("检验项目更新失败");
        }else {
            //新增
            inspectProject.setHandle( projectHandle );
            inspectProject.setCreatedDateTime( now );
            inspectProject.setStatus( "Y" );
            count = inspectProjectMapper.insert( inspectProject );

            if(count <= 0) throw BusinessException.build("检验项目新增失败");
        }

        insertProject( projectList , projectHandle , site ,dataGroupBo );

    }

    /**
     * 检验明细验证
     * 数据类型  数值/N  布尔/B  数据字段/L  文本/T  公式/F
     * 数值 必须有上下限、标准值
     * 数据字段 必须有数组名
     */
    private void insertProject(List<Map> projectList , String projectBo ,String site ,String dcGroupBo){
        String item ;
        String itemDesc ;
        String dataType ;
        String checkStandard ;
        String standardValue ;
        String lowerLimit ;
        String upperLimit ;
        String sampleQty ;
        String arrayName ;
        String sourceData ;
        String report ;

        //删除原有明细项
        inspectProjectDetailService.delete(
                new EntityWrapper<InspectProjectDetail>()
                .eq("PROJECT_BO" , projectBo ));

        for ( Map project : projectList ){
            InspectProjectDetail inspectProjectDetail = new InspectProjectDetail();
            dataType = (String)project.get("dataType");
            item = (String)project.get("item");
            itemDesc = (String)project.get("itemDesc");
            checkStandard = (String)project.get("checkStandard");
            sampleQty = (String)project.get("sampleQty");
            arrayName = (String)project.get("arrayName");
            sourceData = (String)project.get("sourceData");
            report = (String)project.get("report");

            List<DcParameter>  parameters= dcParameterService.selectList(
                    new EntityWrapper<DcParameter>()
                    .eq("DC_GROUP_BO", dcGroupBo )
                    .eq("PARAMETER_NAME",item )
            );

            if ( parameters.isEmpty() ){
                throw BusinessException.build("参数编号【" + item + "】不属于数据收集组【"+ HandleEnum.DC_GROUP.getPart( dcGroupBo ,1 ) +"】");
            }

            if ( "N".equals( dataType ) ){
                //数值字段需要检查输入的标准值、上限、下限
                standardValue = (String)project.get("standardValue");
                lowerLimit = (String)project.get("lowerLimit");
                upperLimit = (String)project.get("upperLimit");
                if ( StringUtils.isBlank(standardValue) ){
                    throw BusinessException.build("请填写标准值");
                }
                if ( StringUtils.isBlank(lowerLimit) ){
                    throw BusinessException.build("请填写下限值");
                }
                if ( StringUtils.isBlank(upperLimit) ){
                    throw BusinessException.build("请填写上限值");
                }
                BigDecimal standard = new BigDecimal( standardValue );
                BigDecimal lower = new BigDecimal( lowerLimit );
                BigDecimal upper = new BigDecimal( upperLimit );

                if ( lower.compareTo( upper ) == 1 ){
                    throw BusinessException.build("下限值不可高于上限值");
                }

                if ( standard.compareTo( upper ) == 1 ){
                    throw BusinessException.build("标准值不可高于上限值");
                }
                if ( standard.compareTo( lower ) == -1 ){
                    throw BusinessException.build("标准值不可低于下限值");
                }

                inspectProjectDetail.setStandardValue( standard );
                inspectProjectDetail.setLowerLimit( lower );
                inspectProjectDetail.setUpperLimit( upper );

            }else if ( "L".equals( dataType ) ){

               InspecArray inspecArray = inspecArrayService.selectById( HandleBOConstants.INSPEC_ARRAY_BO + ":" + site + "," + arrayName );
               if ( inspecArray == null ){
                   throw BusinessException.build("检验项目数组["+ arrayName +"]不存在");
               }else {
                   inspectProjectDetail.setArrayName( arrayName );
               }

            }

            //补充字段
            inspectProjectDetail.setProjectBo( projectBo );
            inspectProjectDetail.setItem( item );
            inspectProjectDetail.setItemDesc( itemDesc );
            inspectProjectDetail.setCheckStandard( checkStandard );
            inspectProjectDetail.setDataType( dataType );
            if ( !StringUtils.isBlank( sampleQty ) ){
                inspectProjectDetail.setSampleQty( new BigDecimal( sampleQty ) );
            }
            if ( !StringUtils.isBlank( sourceData ) ){
                if ( !"N".equals( dataType ) ){
                    throw BusinessException.build("参数编号的数据类型非数值，不可以填写源数据数量!");
                }

                inspectProjectDetail.setSourceData( new BigDecimal( sourceData ) );
            }
            inspectProjectDetail.setReport( report );
            inspectProjectDetail.setHandle( UUID.randomUUID().toString() );
            inspectProjectDetailService.insert( inspectProjectDetail );

        }
    }

}